<template>
  <!-- form表单 -->
  <el-form label-width="100px">
    <!-- SPU名称 input输入框 -->
    <el-form-item label="SPU名称">
      <el-input placeholder="SPU名称" v-model="spuForm.spuName"></el-input>
    </el-form-item>

    <!-- 品牌 select选择框 -->
    <el-form-item label="品牌">
      <el-select v-model="spuForm.tmId">
        <el-option :value="(tm.id as number)" :label="tm.tmName" v-for="(tm, index) in trademarkList"
          :key="tm.id"></el-option>
      </el-select>
    </el-form-item>

    <!-- SPU描述 input输入框 -->
    <el-form-item label="SPU描述">
      <el-input placeholder="SPU描述" type="textarea" rows="4" v-model="spuForm.description"></el-input>
    </el-form-item>

    <!-- upload 照片墙 -->
    <el-form-item label="SPU图片">
      <el-upload 
        v-model:file-list="(spuImageList as any)" 
        action="/app-dev/admin/product/fileUpload"
        list-type="picture-card" 
        :on-preview="handlePictureCardPreview" 
        :on-remove="handleRemove"
        :on-success="handleSuccess">
        <el-icon><Plus /></el-icon>
      </el-upload>
      <el-dialog v-model="dialogVisible">
        <img w-full :src="dialogImageUrl" alt="Preview Image">
      </el-dialog>
    </el-form-item>

    <!-- 销售属性 select选择框 -->
    <el-form-item label="销售属性">
      <el-select v-model="saleAttrIdName"  :placeholder="unUsedSaleAttrList.length?`还有${unUsedSaleAttrList.length}未选择`:'没有啦！！！'">
        <el-option :value="`${unUsedSaleAttr.id}:${unUsedSaleAttr.name}`" :label="unUsedSaleAttr.name" v-for="(unUsedSaleAttr,index) in unUsedSaleAttrList" :key="unUsedSaleAttr.id"></el-option>
      </el-select>
      <!-- 按钮 -->
      <el-button type="primary" :disabled="!saleAttrIdName" @click="addSaleAttr">添加销售属性</el-button>
      <!-- 表格 -->
      <el-table border stripe :data="spuSaleAttrList">
        <el-table-column label="序号" align="center" type="index" width="80"></el-table-column>
        <el-table-column label="属性名" prop="saleAttrName"></el-table-column>
        <el-table-column label="属性值名称列表" prop="">
          <!-- 插槽 -->
          <template v-slot="{ row, $index }">
						<!-- x号调用的事件 @close="handleClose(tag)" -->
						<el-tag
            @close="row.spuSaleAttrValueList.splice(index,1)"
							v-for="(saleAttrValue, index) in row.spuSaleAttrValueList"
							:key="saleAttrValue.id"
							class="mx-1"
							closable
							:disable-transitions="false"
						>
							{{ saleAttrValue.saleAttrValueName }}
						</el-tag>
						<!-- 
              v-if="inputVisible"
              v-model="inputValue" 
              @keyup.enter="handleInputConfirm"
							@blur="handleInputConfirm"
            -->
						<el-input 
            @keyup.enter="$event.target.blur()"
            @blur="handleInputConfirm(row)"
            v-model="row.saleAttrValueName"
            v-if="row.isEdit"
            ref="InputRef" class="ml-1 w-20" size="small" />
						<!-- 
              v-else
              @click="showInput" 
            -->
						<el-button @click="showInput(row)" v-else class="button-new-tag ml-1" size="small">
							添加
						</el-button>
					</template>
        </el-table-column>
        <el-table-column label="操作">
          <template v-slot="{ row, $index }">
						<el-button 
            type="danger" 
            size="small" 
            icon="ele-Delete" 
            title="删除销售属性"
            @click="spuSaleAttrList.splice($index,1)"
            ></el-button>
					</template>
        </el-table-column>
      </el-table>
    </el-form-item>

    <!-- 两个按钮 -->
    <el-form-item>
      <el-button :disabled="!spuSaleAttrList.length" type="primary" @click="save">保存</el-button>
      <el-button @click="emits('changeState',1)">取消</el-button>
    </el-form-item>
  </el-form>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { useCategoryStore } from '@/stores/category';
export default defineComponent({
  name: 'SpuForm'
})
</script>
<script lang="ts" setup>
// 引入数据类型
import type { SpuData, BaseSaleAttrData, SpuImageData, SpuSaleAttrData,ResponseData } from '@/api/spu';
// 引入ref onMounted computed
import { ref, onMounted,computed,nextTick } from 'vue'
// 引入深拷贝
import { cloneDeep } from 'lodash';
// 引入 upload 相关一
import { Plus } from '@element-plus/icons-vue'
// 引入 upload 相关二  引入 ElMessage
import { ElMessage, type UploadProps, type UploadUserFile } from 'element-plus'
// 引入api 
import spuApi from '@/api/spu'
// 引入api
import skuApi from '@/api/sku'
// 引入api 数据类型
import trademarkApi, { type TrademarkData } from '@/api/trademark'


// 接收父组件传递的参数
// 父组件传递的数据是为了让子组件使用而不是让你改
const props = defineProps<{
  spu: SpuData
}>()
// 把接收到的row给深拷贝一份，后期用来收集数据
// 点的是添加，这个spuForm是没有id的
// 点的是修改，这个spuForm是有id的
const spuForm = ref(cloneDeep(props.spu))


// 拷贝的upload照片墙逻辑
const dialogImageUrl = ref('')
const dialogVisible = ref(false)

const handleRemove: UploadProps['onRemove'] = (uploadFile, uploadFiles) => {
  // console.log(uploadFile, uploadFiles)
  spuImageList.value= uploadFiles as any
}

const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
  dialogImageUrl.value = uploadFile.url!
  dialogVisible.value = true
}
// 上传图片成功的回调
const handleSuccess:UploadProps['onSuccess'] = (response, uploadFile, uploadFiles) => {
  console.log(response, uploadFile, uploadFiles);
  // 把上传以后的所有的照片对象组成的数组存起来
  spuImageList.value = uploadFiles as any
} 




/* 发请求获取初始化的动态数据 */
// 把请求发送成功获取到的数据存到本地
const baseSaleAttrList = ref<BaseSaleAttrData[]>([])
const trademarkList = ref<TrademarkData[]>([])
const spuImageList = ref<SpuImageData[]>([])
const spuSaleAttrList = ref<SpuSaleAttrData[]>([])
// 点击的是添加 需要发送的请求
const getInitAddSpuFormData = async () => {
  // 获取所有的销售属性列表
  // http://localhost:3000/app-dev/admin/product/baseSaleAttrList
  const promise1 = spuApi.getBaseSaleAttrList()
  // 获取所有的品牌列表
  // http://localhost:3000/app-dev/admin/product/baseTrademark/getTrademarkList
  const promise2 = trademarkApi.getList()
  // Promise.all统一发送请求
  try {
    // 统一发送请求
    const result = await Promise.all([promise1, promise2])
    // 发送请求成功后将数据存到本地
    baseSaleAttrList.value = result[0]
    trademarkList.value = result[1]
  } catch (error) {
    ElMessage.error('获取初始化数据失败--添加')
  }
}
// 点击的是修改 需要发送的请求
const getInitUpdateSpuFormData = async () => {
  // 获取所有的销售属性列表
  // http://localhost:3000/app-dev/admin/product/baseSaleAttrList
  const promise1 = spuApi.getBaseSaleAttrList()
  // 获取所有的品牌列表
  // http://localhost:3000/app-dev/admin/product/baseTrademark/getTrademarkList
  const promise2 = trademarkApi.getList()
  // 根据spuid获取spu图片列表
  // http://localhost:3000/app-dev/admin/product/spuImageList/5339
  const promise3 = skuApi.getSpuImageList(spuForm.value.id as number)
  // 根据spuid获取spu自己的销售属性列表
  // http://localhost:3000/app-dev/admin/product/spuSaleAttrList/5339
  const promise4 = skuApi.getSpuSaleAttrList(spuForm.value.id as number)

  /* *******************Promise.all*******************************
    Promise.all是一个方法，方法的本质就是函数，函数就要知道三要素
    功能：同时处理多个promise
    参数：promise对象的数组
    返回值：一个新的promise
    如果数组当中所有的promise都是成功的，那么返回的promise就是成功的，
    成功的结果是所有的数组当中promise成功的结果组成的数组。
    如果数组当中有一个promise是失败的，那么返回的promise就是失败的
    失败的原因就是数组当中第一个失败的promise失败的原因。
  ************************************************************** */
  // Promise.all统一发送请求
  try {
    // 统一发送请求
    const result = await Promise.all([promise1, promise2, promise3, promise4])
    // 发送请求成功后将数据存到本地
    baseSaleAttrList.value = result[0]
    trademarkList.value = result[1]

    // 不能直接给值，因为opload里面需要的照片是name和uri
    // spuImageList.value = result[2]
    // 所以需要把请求回来的spu图片列表每个图片添加name和url，为了upload照片墙组件可以展示
    // 1. 定义一个 imgList 来接收 result[2]
    let imgList = result[2]
    // 2. 遍历 imgList 为每个对象都添加 name=imgName url=imgUrl 属性
    imgList.forEach(item => {
      item.name = item.imgName
      item.url= item.imgUrl
    })
    // 3. 把 imgList 赋值给 spuImageList.value
    spuImageList.value = imgList

    spuSaleAttrList.value = result[3]
  } catch (error) {
    ElMessage.error('获取初始化数据失败--修改')
  }
}
// 页面挂载完成发送请求获取动态数据
onMounted(() => {
  // 判断传过来的值是否有id
  if (spuForm.value.id) {
    // 点击的是修改 发送4个请求
    getInitUpdateSpuFormData()
  } else {
    // 点击的是添加 发送2个请求
    getInitAddSpuFormData()
  }
})


// 通过所有的销售属性列表和spu自己的销售属性列表计算未选择的销售属性列表
// 从所有的属性列表当中去过滤，不在spu自己的销售属性列表当中的项
// const unUsedSaleAttrList = computed(() => {
//   return baseSaleAttrList.value.filter(item => {
//     return  spuSaleAttrList.value.every(item1 => {
//       return item1.saleAttrName !== item.name
//     })
//   })
// })
const unUsedSaleAttrList = computed(() =>
	baseSaleAttrList.value.filter((item) =>
		spuSaleAttrList.value.every((item1) => item1.saleAttrName !== item.name)
	)
);

// 点击取消返回到spu列表页
const emits = defineEmits(['changeState'])

// 收集添加销售属性
const saleAttrIdName = ref('')
// 点击 添加销售属性 按钮
const addSaleAttr = () => {
  // 使用 .split(':') 方法 把saleAttrIdName解构出来
  let [baseSaleAttrId,saleAttrName] = saleAttrIdName.value.split(':')
  // 把刚才收集到的串构造成需要的对象
  let obj = {
    baseSaleAttrId,
		saleAttrName,
    spuSaleAttrValueList:[]
  }
  // push到spuSaleAttrList
  spuSaleAttrList.value.push(obj)
  // 清空选择框数据
  saleAttrIdName.value=''
}

const InputRef=ref()
const showInput=(row:SpuSaleAttrData)=>{
  row.isEdit=true
  nextTick(()=>{
    InputRef.value.focus()
  })
}

const handleInputConfirm=(row:SpuSaleAttrData)=>{
  let {baseSaleAttrId,saleAttrValueName}=row
  if(!saleAttrValueName || saleAttrValueName.trim()){
    ElMessage.error('请输入合法的数据')
    row.saleAttrValueName=''
    row.isEdit=false
    return
  }

  let isRepeat=row.spuSaleAttrValueList.some(item=>item.saleAttrValueName===saleAttrValueName)
  if(isRepeat){
    ElMessage.error('属性值名称不能重复')
    row.saleAttrValueName=''
    row.isEdit=false
    return
  }

  let obj={baseSaleAttrId,saleAttrValueName}
  row.spuSaleAttrValueList.push(obj)
  row.saleAttrValueName=''
  row.isEdit=false
}
const categoryStore=useCategoryStore()
const save=async()=>{
  //定义数据
  let spu =spuForm.value
  // 整理category3Id
  spu.category3Id=categoryStore.category3Id
  spu.spuImageList=spuImageList.value.map(item=>{
    return {
      imgName:item.name,
      imgUrl:item.imgUrl || (item.response as ResponseData).data
    }
  })
  spuSaleAttrList.value.forEach(item=>{
    delete item.isEdit
    delete item.saleAttrValueName
  })

  spu.spuSaleAttrList=spuSaleAttrList.value
  try {
    await spuApi.addOrUpdate(spu)
    ElMessage.success('保存成功')
    emits('changeState',1)
  } catch (error) {
    ElMessage.error('保存spu失败')
  }


}
</script>

<style lang="less" scoped></style>
